#include"pin.h"

pin::pin(void)
{
	_port   = 0;
	_bit    = 0;
	_pinDir = INPUT;
	_invert = FALSE;
	_mask = 0x00;
}

void pin::setInvert(state s)
{
	_invert = s;
}

void pin::setup(byte port, byte bit, pinDirection dir)
{
	_pinDir = dir;
	_bit = bit;
	_port = port;
	_mask = 0x01 << _bit;;

	switch(port)
	{
		case PA:
		{
			if(_pinDir == OUTPUT)
				DDRA |= _mask;
				else
				DDRA &= ~_mask;
			_port=PA;
			break;
		}
		case PB:
		{
			if(_pinDir == OUTPUT)
				DDRB |= _mask;
			else
				DDRB &= ~_mask;
			_port=PB;
			break;
		}
		case PC:
		{
			if(_pinDir == OUTPUT)
				DDRC |= _mask;
			else
				DDRC &= ~_mask;
			_port=PC;
			break;
		}
		case PD:
		{
			if(_pinDir == OUTPUT)
				DDRD |= _mask;
			else
				DDRD &= ~_mask;
			_port=PD;
			break;
		}
	}
}

void pin::pinOn(void)
{
	switch(_port)
	{
	case PA:
		{
			PORTA |= _mask;
			break;
		}

	case PB:
		{
			PORTB |= _mask;
			break;
		}
	
	case PC:
		{
			PORTC |= _mask;
			break;
		}

	case PD:
		{
			PORTD |= _mask;
			break;
		}
	}
}

void pin::pinOff(void)
{
	switch(_port)
	{
	case PA:
		{
			PORTA &= ~_mask;
			break;
		}
	case PD:
		{
			PORTD &= ~_mask;
			break;
		}

	case PB:
		{
			PORTB &= ~_mask;
			break;
		}
	
	case PC:
		{
			PORTC &= ~_mask;
			break;
		}
	}
}

void pin::set(state s)
{
	if(_invert==TRUE)
	{
		if(s==TRUE)
			pinOff();
		else
			pinOn();
	}
	else
	{
		if(s==TRUE)
			pinOn();
		else
			pinOff();
	}
}

void pin::set(void)
{
	if(_invert==TRUE)
		pinOff();
	else
		pinOn();
}

void pin::clear(void)
{
	if(_invert==TRUE)
		pinOn();
	else
		pinOff();
}

state pin::get(void)
{
	if(_invert==TRUE)
		return(nRead());
	else
		return(read());
}

state pin::read(void)
{
	if(_pinDir)
	{
		switch(_port)
		{
			case PD:
			{
				return((PORTD & _mask)?TRUE:FALSE);
				break;
			}
			case PB:
			{
				return((PORTB & _mask)?TRUE:FALSE);
				break;
			}
			case PC:
			{
				return((PORTC & _mask)?TRUE:FALSE);
				break;
			}
			case PA:
			{
				return((PORTA & _mask)?TRUE:FALSE);
				break;
			}
			default :
				break;
		}
	}
	else
	{
		switch(_port)
		{
			case PD:
			{
				return((PIND & _mask)?TRUE:FALSE);
				break;
			}
			case PB:
			{
				return((PINB & _mask)?TRUE:FALSE);
				break;
			}
			case PC:
			{
				return((PINC & _mask)?TRUE:FALSE);
				break;
			}
			case PA:
			{
				return((PINA & _mask)?TRUE:FALSE);
				break;
			}
			default :
				break;
		}
	}
	return(FALSE);
}

state pin::nRead(void)
{
	if(read()==TRUE)
		return(FALSE);
	else
		return(TRUE);
}

void pin::setDir(pinDirection dir)
{
	_pinDir = dir;
	this->setup(_port, _bit,_pinDir);
}

pinDirection pin::getDir(void)
{
	return(_pinDir);
}

void pin::setBit(byte bit)
{
	_bit = bit;
	setup(_port, _bit, _pinDir);
}

byte pin::getBit(void)
{
	return(_bit);
}
